home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / dobbs / v17n05 / ipx.exe / IPX_ESR.ASM < prev    next >
Encoding:
Assembly Source File  |  1992-01-26  |  15.3 KB  |  421 lines

  1. ; *************************************************************************************************
  2. ; *
  3. ; *    Title:    ESRS.ASM
  4. ; *    Copyright (c) January 1991, Ryu Consulting, 916/722-1939
  5. ; *    Written by Rahner James
  6. ; *
  7. ; *    This file contains the default Event Service Routine for listening and talking packets
  8. ; *
  9. ; *************************************************************************************************
  10.  
  11. _ESRS_ASM_    equ    1
  12.  
  13. ifdef    LARGEMODEL
  14.     .model    large,c
  15. else
  16.     .model    small,c
  17. endif
  18.  
  19.  
  20. ADDRESS_S struct
  21.     network        dw    ?,?    ; Network number
  22.     node        dw    3 dup(?); Node address on that network
  23.     socket        dw    ?    ; Socket number on that node
  24. ADDRESS_S ends
  25.  
  26.  
  27. IPX_PACKET_S struct
  28.     next        dd    ?    ; Used by IPX/SPX when the ECB is active
  29.     function    dd    ?    ; Called after packet sent/recd, called ESR
  30.     in_use        db    ?    ; Set to !0 by IPX/SPX when packet is in use
  31.     completion_code    db    ?    ; Set by IPX/SPX after packet task is complete
  32.     socket        dw    ?    ; Socket to use for this ECB
  33.     IPX_work    dd    ?    ; Workspace used internally by IPX
  34.     driver_work    dd    ?,?,?    ; Workspace used internally by the IPX driver
  35.     dest_address    db    6 dup(?); Destination address for packet
  36.     fragment_count    dw    ?    ; Fragments descriptors that follow
  37.     hdr        dd    ?    ; -> IPX/SPX packet descriptor to use
  38.     size_hdr    dw    ?    ; Size of the IPX(30) or SPX(42) descriptor
  39.     buffer_ptr    dd    ?    ; -> data buffer to use for transmission/reception
  40.     buffer_size    dw    ?    ; Number of bytes in that buffer
  41.  
  42.     next_allocated    dd    ?    ; -> next allocated packet structure
  43.     next_sibling    dd    ?    ; -> next packet for stream and condition
  44.     parent        dd    ?    ; -> parent stream definition packet
  45.     default_buffer    dd    ?    ; -> default buffer to use for IPX or SPX
  46.     default_size    dw    ?    ; Size of the default buffer
  47.     done_flag    dd    ?    ; Set by the ESR with the completion code
  48.  
  49.     checksum    dw    ?    ; Dummy checksum of the 30-byte packet header
  50.     packet_length    dw    ?    ; Length of the complete IPX packet, filled by IPX/SPX
  51.     control        db    ?    ; Transport control byte for internetwork bridges
  52.     packet_type    db    ?    ; Packet type: IPX(4)/SPX(5), defined by Xerox
  53.  
  54.     dest_network    dd    ?    ; Destination network address
  55.     dest_node    db    6 dup(?); Destination node address
  56.     dest_socket    dw    ?    ; Destination socket
  57.  
  58.     src_network    dd    ?    ; Source network address
  59.     src_node    db    6 dup(?); Source node address
  60.     src_socket    dw    ?    ; Source socket
  61. IPX_PACKET_S ends
  62.  
  63.  
  64. XPX_STREAM_S struct
  65.     next        dd    ?    ; -> next stream structure that has been opened
  66.     first_allocated    dd    ?    ; -> first allocated packet for this handle
  67.     last_allocated    dd    ?    ; -> last allocated packet for this handle
  68.     first_unread    dd    ?    ; -> first unread packet
  69.     last_unread    dd    ?    ; -> last unread packet in the list
  70.     first_free    dd    ?    ; -> first packet available for talking
  71.     first_error    dd    ?    ; -> first packet that encountered an error
  72.     last_error    dd    ?    ; -> last packet that encountered an error
  73.  
  74.     dest_network    dd    ?    ; Destination network address
  75.     dest_node    db    6 dup(?); Destination node address
  76.     dest_socket    dw    ?    ; Destination socket
  77.     local_target    db    6 dup(?); Node address of the local target for the destination
  78.     connection_ID    dw    ?    ; Connection ID used for SPX
  79.     total_talkers    dw    ?    ; Number of talkers allocated to this stream
  80.     total_listeners    dw    ?    ; Number of listeners allocated to this stream
  81.     unread_count    dw    ?    ; Number of packets unread by application
  82.     free_count    dw    ?    ; Number of packets ready for talking
  83.     maximum_unread    dw    ?    ; Maximum number of unread packets that have occurred so far
  84.     error_count    dw    ?    ; Number of unprocessed error packets
  85.  
  86.     total_transmissions dd    ?    ; Number of transmissions performed by this stream
  87.     total_receptions    dd    ?    ; Number of receptions performed by this stream
  88.     total_errors    dd    ?    ; Number of errors encountered by this stream
  89. XPX_STREAM_S ends
  90.  
  91. .data
  92.     extern    _Ignore_Nomatch:byte, _Our_Address:word, IPX_Vector:dword, _First_Stream:dword
  93.     extern    _First_Nomatch:dword, _Last_Nomatch:dword, _Total_Nomatchs:word
  94.  
  95. .code
  96.  
  97. Last_Broad_Ptr        dw    0,0    ; -> last checked broadcast stream, must be in code segment
  98.  
  99.  
  100. ; *************************************************************************************************
  101. ; *
  102. ; *    void far TALK_ESR( void )
  103. ; *    Event Service Routine (ESR) for IPX functions and their talking packets
  104. ; *
  105. ; *    Given:
  106. ; *        AL = 0 if AES called this ESR, 0xff if this is a normal event (only possibility)
  107. ; *        ES:SI -> ECB that just finished talking
  108. ; *
  109. ; *    Returns:
  110. ; *        Packet either glued onto the free list or the error list
  111. ; *
  112. ; *    Note:
  113. ; *        Interrupts are enabled at this point and should stay that way
  114. ; *
  115. ; *************************************************************************************************
  116. talk_esr proc far
  117.  
  118. ; *
  119. ; * See if we need to set the done flag
  120. ; *
  121.     lds    bx, es:[si].IPX_PACKET_S.done_flag    ; DS:BX -> process done flag
  122.     mov    cl, es:[si].IPX_PACKET_S.completion_code
  123.     mov    ax, ds
  124.     or    ax, bx
  125.     jz    @F            ; If DS:BX -> NULL, just skip it
  126.     mov    [bx], cl        ; Set the flag with our completion code
  127.     mov    word ptr es:[si].IPX_PACKET_S.done_flag, 0    ; Make it NULL for the next guy
  128.     mov    word ptr es:[si].IPX_PACKET_S.done_flag+2, 0
  129.  
  130. ; *
  131. ; * Check whether the packet goes in the error list or the free list
  132. ; *
  133. @@:    lds    bx, es:[si].IPX_PACKET_S.parent        ; DS:BX -> parent structure
  134.     or    cl, cl                    ; See if we got a transmission error
  135.     jnz    talk20_esr                ; Jump if we got one
  136.  
  137. ; *
  138. ; * Here's where we process the good transmissions
  139. ; *
  140.     add    word ptr [bx].XPX_STREAM_S.total_transmissions, 1
  141.     adc    word ptr [bx].XPX_STREAM_S.total_transmissions+2, 0
  142.     inc    [bx].XPX_STREAM_S.free_count;
  143.  
  144.     mov    cx, word ptr [bx].XPX_STREAM_S.first_free    ; DX:CX -> first free
  145.     mov    dx, word ptr [bx].XPX_STREAM_S.first_free+2
  146.     mov    word ptr [bx].XPX_STREAM_S.first_free, si    ; Set us as the new first
  147.     mov    word ptr [bx].XPX_STREAM_S.first_free+2, es
  148.     mov    word ptr es:[si].IPX_PACKET_S.next_sibling, cx    ; Place us with our brothers and sisters
  149.     mov    word ptr es:[si].IPX_PACKET_S.next_sibling+2, dx
  150.  
  151. talk10_esr:
  152.     ret
  153.  
  154. ; *
  155. ; * Here's where we take care of our challenged packets
  156. ; *
  157. talk20_esr:
  158.     add    word ptr [bx].XPX_STREAM_S.total_errors, 1
  159.     adc    word ptr [bx].XPX_STREAM_S.total_errors+2, 0
  160.     inc    [bx].XPX_STREAM_S.error_count
  161.  
  162.     mov    cx, word ptr [bx].XPX_STREAM_S.last_error    ; DX:CX -> last error packet
  163.     mov    dx, word ptr [bx].XPX_STREAM_S.last_error+2
  164.     mov    word ptr [bx].XPX_STREAM_S.last_error, si    ; Set us as the new last error
  165.     mov    word ptr [bx].XPX_STREAM_S.last_error+2, es
  166.     mov    word ptr es:[si].IPX_PACKET_S.next_sibling, 0    ; Place us with our brothers and sisters
  167.     mov    word ptr es:[si].IPX_PACKET_S.next_sibling+2, 0
  168.  
  169.     mov    ax, cx                        ; See if we need to do the first as well
  170.     or    ax, dx
  171.     jnz    @F
  172.  
  173.     mov    word ptr [bx].XPX_STREAM_S.first_error, si    ; Set us as the new first error
  174.     mov    word ptr [bx].XPX_STREAM_S.first_error+2, es
  175.     ret
  176.  
  177. @@:    mov    ds, dx                        ; DS:BX -> the first born
  178.     mov    bx, cx
  179.     mov    word ptr [bx].IPX_PACKET_S.next_sibling, si    ; Point the old end at us
  180.     mov    word ptr [bx].IPX_PACKET_S.next_sibling+2, es
  181.     ret
  182.  
  183. talk_esr endp
  184.  
  185.  
  186. ; *************************************************************************************************
  187. ; *
  188. ; *    void far LISTEN_ESR( void )
  189. ; *    Event Service Routine (ESR) for IPX functions and their listening packets
  190. ; *
  191. ; *    Given:
  192. ; *        AL = 0 if AES called this ESR, 0xff if this is a normal event (only possibility)
  193. ; *        ES:SI -> ECB that just got something
  194. ; *
  195. ; *    Returns:
  196. ; *        Packet put at the end of the unread packet list of the stream it was intended for
  197. ; *
  198. ; *    Note:
  199. ; *        Interrupts are enabled at this point and should stay that way
  200. ; *        This packet may not be put with its parent if there are multiple parents
  201. ; *        associated with one socket
  202. ; *
  203. ; *************************************************************************************************
  204. listen_esr proc far
  205.  
  206.     mov    ax, @Data                    ; DS = our data segment
  207.     mov    ds, ax
  208. ; *
  209. ; * First see if we sent it as a broadcast and it got back to us
  210. ; *
  211.     mov    ax, _Our_Address.ADDRESS_S.node+4        ; Do it this way to eliminate the setup
  212.     cmp    word ptr es:[si].IPX_PACKET_S.src_node+4, ax    ; for a CMPSW and the LSBSMW (Least
  213.     jne    listen10_esr                    ; Significant B.S. Motorola Word) has the
  214.     mov    ax, _Our_Address.ADDRESS_S.node+2        ; greatest chance of being different and
  215.     cmp    word ptr es:[si].IPX_PACKET_S.src_node+2, ax    ; this condition should happen rarely
  216.     jne    listen10_esr
  217.     mov    ax, _Our_Address.ADDRESS_S.node
  218.     cmp    word ptr es:[si].IPX_PACKET_S.src_node, ax
  219.     jne    listen10_esr
  220.     mov    ax, _Our_Address.ADDRESS_S.network+2
  221.     cmp    word ptr es:[si].IPX_PACKET_S.src_network+2, ax
  222.     jne    listen10_esr
  223.     mov    ax, _Our_Address.ADDRESS_S.network
  224.     cmp    word ptr es:[si].IPX_PACKET_S.src_network, ax
  225.     jne    listen10_esr
  226.  
  227. listen_again_buckwheat:
  228.     mov    bx, 4            ; BX = IPX Listen For Packet command
  229.     call    dword ptr IPX_Vector    ; Call the IPX function
  230.     ret
  231.  
  232. ; *
  233. ; * See if we need to set the done flag
  234. ; *
  235. listen10_esr:
  236.     mov    ax, es:[si].IPX_PACKET_S.packet_length    ; Change this into a more rational format
  237.     xchg    ah, al
  238.     sub    ax, es:[si].IPX_PACKET_S.size_hdr
  239.     mov    es:[si].IPX_PACKET_S.packet_length, ax
  240.  
  241.     lds    bx, es:[si].IPX_PACKET_S.done_flag    ; DS:BX -> process done flag
  242.     mov    cl, es:[si].IPX_PACKET_S.completion_code
  243.     mov    ax, ds
  244.     or    ax, bx
  245.     jz    listen20_esr                    ; If DS:BX -> NULL, just skip it
  246.     mov    [bx], cl                    ; Set the flag with our completion code
  247.     mov    word ptr es:[si].IPX_PACKET_S.done_flag, 0    ; Make it NULL for the next guy
  248.     mov    word ptr es:[si].IPX_PACKET_S.done_flag+2, 0
  249.  
  250. ; *
  251. ; * Check whether the packet goes in the error list or the free list
  252. ; *
  253. listen20_esr:
  254.     lds    bx, es:[si].IPX_PACKET_S.parent        ; DS:BX -> parent structure
  255.     or    cl, cl                    ; See if we got a reception error
  256.     jz    listen40_esr                ; Jump if we have an unimpaired reception
  257.  
  258. ; *
  259. ; * Here's where we take care of our datistically challenged packets
  260. ; *
  261.     add    word ptr [bx].XPX_STREAM_S.total_errors, 1
  262.     adc    word ptr [bx].XPX_STREAM_S.total_errors+2, 0
  263.     inc    [bx].XPX_STREAM_S.error_count
  264.  
  265.     mov    cx, word ptr [bx].XPX_STREAM_S.last_error    ; DX:CX -> last error packet
  266.     mov    dx, word ptr [bx].XPX_STREAM_S.last_error+2
  267.     mov    word ptr [bx].XPX_STREAM_S.last_error, si    ; Set us as the new last error
  268.     mov    word ptr [bx].XPX_STREAM_S.last_error+2, es
  269.     mov    word ptr es:[si].IPX_PACKET_S.next_sibling, 0    ; Place us with our brothers and sisters
  270.     mov    word ptr es:[si].IPX_PACKET_S.next_sibling+2, 0
  271.  
  272.     mov    ax, dx                        ; See if we are the only packet here
  273.     or    ax, cx
  274.     jnz    @F                        ; Skip out of this ESR if we are not alone
  275.  
  276.     mov    word ptr [bx].XPX_STREAM_S.first_error, si    ; Set us as the new first error
  277.     mov    word ptr [bx].XPX_STREAM_S.first_error+2, es
  278.     ret
  279.  
  280. @@:    mov    ds, dx                        ; DS:BX -> the first born
  281.     mov    bx, cx
  282.     mov    word ptr [bx].IPX_PACKET_S.next_sibling, si    ; Point the old end at us
  283.     mov    word ptr [bx].IPX_PACKET_S.next_sibling+2, es
  284.     ret
  285.  
  286. ; *
  287. ; * Here's where we process the good transmissions
  288. ; *
  289. listen40_esr:
  290.     push    ds                        ; DX:CX -> the first stream structure
  291.     mov    ax, @Data
  292.     mov    ds, ax
  293.     mov    cx, word ptr _First_Stream
  294.     mov    dx, word ptr _First_Stream+2
  295.     pop    ds
  296.     mov    Last_Broad_Ptr, 0
  297.     mov    Last_Broad_Ptr+2, 0
  298.  
  299. listen50_esr:
  300.     cmp    [bx].XPX_STREAM_S.total_listeners, 0        ; See if it's a READ ONLY stream
  301.     jz    not_parent                    ; Skip this one if it is READ ONLY
  302.  
  303.     mov    ax, word ptr [bx].XPX_STREAM_S.dest_node    ; See if our parent will take anything (all 0xFF's)
  304.     and    ax, word ptr [bx].XPX_STREAM_S.dest_node+2
  305.     and    ax, word ptr [bx].XPX_STREAM_S.dest_node+4
  306.     inc    ax
  307.     jnz    @F                        ; Skip if it is not a broadcast type
  308.     mov    Last_Broad_Ptr, bx                ; Save this for later
  309.     mov    Last_Broad_Ptr+2, ds
  310.     jmp    short not_parent                ; Still not necessarily the right one
  311.  
  312. @@:    mov    ax, word ptr [bx].XPX_STREAM_S.local_target+4    ; Match the parent destination up first
  313.     cmp    word ptr es:[si].IPX_PACKET_S.src_node+4, ax
  314.     jne    not_parent                    ; Skip if this is not my mommy
  315.     mov    ax, word ptr [bx].XPX_STREAM_S.local_target+2
  316.     cmp    word ptr es:[si].IPX_PACKET_S.src_node+2, ax
  317.     jne    not_parent
  318.     mov    ax, word ptr [bx].XPX_STREAM_S.local_target
  319.     cmp    word ptr es:[si].IPX_PACKET_S.src_node, ax
  320.     jne    not_parent
  321.  
  322.     mov    ax, word ptr es:[si].IPX_PACKET_S.src_network+2
  323.     cmp    word ptr es:[si].IPX_PACKET_S.dest_network+2, ax
  324.     jne    not_parent
  325.     mov    ax, word ptr es:[si].IPX_PACKET_S.src_network
  326.     cmp    word ptr es:[si].IPX_PACKET_S.dest_network, ax
  327.     je    found_listener
  328.  
  329. ; *
  330. ; * At this point, the current structure has been determined not to be suitable
  331. ; *
  332. not_parent:
  333.     mov    ax, cx                ; See if we are at the end of our rope
  334.     or    ax, dx
  335.     jz    no_listener            ; No stream match found
  336.  
  337.     mov    ds, dx                ; DS:BX -> next stream definition
  338.     mov    bx, cx
  339.     mov    cx, word ptr [bx].XPX_STREAM_S.next    ; DX:CX -> next stream packet after this one
  340.     mov    dx, word ptr [bx].XPX_STREAM_S.next+2
  341.     jmp    listen50_esr                ; Loop until we poop
  342.  
  343. ; *
  344. ; * Stream ID matches up with the destination address, so we add this packet to that stream list
  345. ; *
  346. found_listener:
  347.     add    word ptr [bx].XPX_STREAM_S.total_receptions, 1
  348.     adc    word ptr [bx].XPX_STREAM_S.total_receptions+2, 0
  349.     inc    [bx].XPX_STREAM_S.unread_count
  350.     mov    ax, [bx].XPX_STREAM_S.unread_count        ; Update our statistics
  351.     cmp    [bx].XPX_STREAM_S.maximum_unread, ax
  352.     jnc    found10_listener                ; Skip if no need to update
  353.     mov    [bx].XPX_STREAM_S.maximum_unread, ax
  354. found10_listener:
  355.     mov    cx, word ptr [bx].XPX_STREAM_S.last_unread    ; DX:CX -> last unread packet
  356.     mov    dx, word ptr [bx].XPX_STREAM_S.last_unread+2
  357.     mov    word ptr [bx].XPX_STREAM_S.last_unread, si    ; Set us as the new last unread packet
  358.     mov    word ptr [bx].XPX_STREAM_S.last_unread+2, es
  359.     mov    word ptr es:[si].IPX_PACKET_S.next_sibling, 0    ; Place us with our new brothers and sisters
  360.     mov    word ptr es:[si].IPX_PACKET_S.next_sibling+2, 0
  361.  
  362.     mov    ax, cx                        ; See if we need to do the first as well
  363.     or    ax, dx
  364.     jnz    @F                        ; All done if there are others
  365.  
  366.     mov    word ptr [bx].XPX_STREAM_S.first_unread, si    ; Set us as the new first unread as well
  367.     mov    word ptr [bx].XPX_STREAM_S.first_unread+2, es
  368.     ret
  369.  
  370. @@:    mov    ds, dx                        ; DS:BX -> the first born
  371.     mov    bx, cx
  372.     mov    word ptr [bx].IPX_PACKET_S.next_sibling, si    ; Point the old end at us
  373.     mov    word ptr [bx].IPX_PACKET_S.next_sibling+2, es
  374.     ret
  375.  
  376. ; *
  377. ; * At this point, the packet is an orphan and must be sent off to farm or be glue
  378. ; *
  379. no_listener:
  380.     lds    bx, dword ptr Last_Broad_Ptr    ; DS:BX -> last found broadcast stream
  381.     mov    ax, ds
  382.     or    ax, bx
  383.     jnz    found_listener        ; If one was found, use that in the last resort
  384.  
  385.     cmp    _Ignore_Nomatch, al    ; See if we just ignore the orphans or adopt them, (AL==0 here)
  386.     jz    no10_listener        ; Skip to adopt
  387.     jmp    listen_again_buckwheat    ; Put back on the mountaintop
  388.  
  389. no10_listener:
  390.     mov    ax, @Data        ; DS = our most lovable data segment
  391.     mov    ds, ax
  392.  
  393.     inc    _Total_Nomatchs
  394.     mov    cx, word ptr _Last_Nomatch            ; DX:CX -> last error packet
  395.     mov    dx, word ptr _Last_Nomatch+2
  396.     mov    word ptr _Last_Nomatch, si            ; Make it point to us
  397.     mov    word ptr _Last_Nomatch+2, es
  398.     mov    word ptr es:[si].IPX_PACKET_S.next_sibling, 0    ; Place us with our new brothers and sisters
  399.     mov    word ptr es:[si].IPX_PACKET_S.next_sibling+2, 0
  400.  
  401.     mov    ax, cx                        ; See if we need to do the first as well
  402.     or    ax, dx
  403.     jnz    @F                        ; All done if there are others
  404.  
  405.     mov    word ptr _First_Nomatch, si            ; Set us as the new first error
  406.     mov    word ptr _First_Nomatch+2, es
  407.     ret
  408.  
  409. @@:    mov    ds, dx                        ; DS:BX -> the first born
  410.     mov    bx, cx
  411.     mov    word ptr [bx].IPX_PACKET_S.next_sibling, si    ; Point the old end at us
  412.     mov    word ptr [bx].IPX_PACKET_S.next_sibling+2, es
  413.     ret
  414.  
  415. listen_esr endp
  416.  
  417.  
  418.     end
  419.  
  420.  
  421.